﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using AutomatedDecisionMaking.Class;
using AutomatedDecisionMaking.Class.Algorithms;

namespace AutomatedDecisionMaking.GUI.MOWmaxWindow
{
    public partial class FrmMaxMOW : Form
    {
        #region Pola prywatne, konstruktor i podstawowa obsługa okna
        private readonly MOWmaxAlgorithm _mAlgorithm;       /// Algorytm realizujący obliczenia

        ///<summary>
        /// Konstrukotr okna analizy największego oczekiwanego żalu
        /// </summary>
        /// <param name="decisionMatrix">Macierz decyzji użytkownika</param>
        public FrmMaxMOW(DecisionMatrix decisionMatrix)
        {
            InitializeComponent();
            _mAlgorithm = new MOWmaxAlgorithm(decisionMatrix);
            ShowPanel1();
        }

        /// <summary>
        /// Wyświetlenie Panelu nr 1
        /// </summary>
        private void ShowPanel1()
        {
            Panel1.Visible = true;
            Panel2.Visible = false;
        }

        /// <summary>
        /// Wyświetlenie Panelu nr 2
        /// </summary>
        private void ShowPanel2()
        {
            Panel1.Visible = false;
            Panel2.Visible = true;
        }

        /// <summary>
        /// Metoda przygotowująca wygląd okna przed jego uruchomieniem.
        /// </summary>
        /// <param name="sender">Obiekt wysyłajacy zdarzenie</param>
        /// <param name="e">Obsługiwane zdarzenie</param>
        private void FrmMinMOW_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < _mAlgorithm.GetDecisionMatrix().ScenarioList.Count; ++i)
            {
                this.p1DataGridView_Weights.Rows.Add();
                this.p1DataGridView_Weights.Rows[i].HeaderCell.Value = "S" + (i + 1);
            }
        }
        #endregion
        
        #region Obsługa przycisków nawigacji
        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku next na panelu 1
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p1ButtonNext_Click(object sender, EventArgs e)
        {
            try
            {
                double sum = 0;
                for (int i = 0; i < _mAlgorithm.GetDecisionMatrix().ScenarioList.Count; ++i)
                    sum += Convert.ToDouble(p1DataGridView_Weights.Rows[i].Cells[0].Value);

                if (sum != 1)
                    throw new ArgumentOutOfRangeException("Suma prawdopodobieństw z poza zakresu!");

                _mAlgorithm.Reset();
                UpdateWindow();
                ShowPanel2();

            }
            catch (Exception exception)
            {
                MessageBox.Show("Nie wprowadzono prawdopodobieństw scenariuszy lub\nsuma prawdopodobieństw jest różna od 1!",
                                "INFORMACJA!",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Information);

                for (int i = 0; i < _mAlgorithm.GetDecisionMatrix().ScenarioList.Count; ++i)
                    p1DataGridView_Weights.Rows[i].Cells[0].Value = "";
            }
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku prev na panelu 2
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p2ButtonPrev_Click(object sender, EventArgs e)
        {
            ShowPanel1();
        }

        /// <summary>
        /// Metoda obsługująca zdarzenie wygenerowane podczad kliknięcia
        /// przycisku begin na panelu 2
        /// </summary>
        /// <param name="sender">Obiekt wywołujący zdarzenie</param>
        /// <param name="e">Rodzaj zdarzenie jakie wystąpiło</param>
        private void p2ButtonBegin_Click(object sender, EventArgs e)
        {
            ShowPanel1();
        }
        #endregion

        #region Obsługa Panelu nr. 1
        /// <summary>
        /// Metoda obsługująca zdarzenie generowane przy zakończeniu edytowania komorki tabeli wag
        /// dla scenariuszy.
        /// </summary>
        /// <param name="sender">Obiekt wysyłajacy zdarzenie</param>
        /// <param name="e">Obsługiwane zdarzenie</param>
        private void p1DataGridView_Weights_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                double doubleValue;
                string cellValue = p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString();
                if (!(double.TryParse(cellValue, out doubleValue)))
                {
                    MessageBox.Show("Wprowadzona wartość musi być liczbą z zakresu <0; 1>!",
                                    "INFORMACJA!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }
                else if (doubleValue < 0 || doubleValue > 1)
                {
                    MessageBox.Show("Wprowadzona wartość musi być liczbą z zakresu <0; 1>!",
                                    "INFORMACJA!",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Information);

                    p1DataGridView_Weights.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = "";
                }
            }
            catch (NullReferenceException exception){}
        }
        #endregion

        #region Aktualzacja zawartości okna
        /// <summary>
        /// Aktualizacja zawartości całego okna po uruchomienu algorytmu.
        /// </summary>
        private void UpdateWindow()
        {
            p2ListBox_WeightedValue.Items.Clear();

            var weights = new List<double>();
            for (int i = 0; i < _mAlgorithm.GetDecisionMatrix().ScenarioList.Count; ++i)
                weights.Add(Convert.ToDouble(p1DataGridView_Weights.Rows[i].Cells[0].Value));
            _mAlgorithm.SetWeights(weights);
            _mAlgorithm.CalculateSolution();

            var weightedValues = _mAlgorithm.GetWeightedValuesStr();
            foreach (string s in weightedValues)
                p2ListBox_WeightedValue.Items.Add(s);

            p2TextBox_MaxWeightedVal.Text = _mAlgorithm.GetMaxWeightedValue().ToString();

            p2Label_Decision.Text = _mAlgorithm.GetDecision();
        }
        #endregion
    }
}
